package com.zbkj.crmeb.store.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.store.model.StoreZoneProduct;
import com.zbkj.crmeb.store.service.StoreZoneProductService;
import com.zbkj.crmeb.system.model.SystemConfig;
import com.zbkj.crmeb.system.service.SystemConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.crmeb.store.dao.StoreZoneDao;
import com.zbkj.crmeb.store.model.StoreZone;
import com.zbkj.crmeb.store.service.StoreZoneService;
import org.springframework.transaction.annotation.Transactional;

/**
* @author Mr.Zhang
* @description StoreZoneServiceImpl 接口实现
* @date 2020-05-28 edit by stivepeim 2020-7-4
*/
@Service
@Transactional
public class StoreZoneServiceImpl extends ServiceImpl<StoreZoneDao, StoreZone> implements StoreZoneService {

    @Resource
    private StoreZoneDao dao;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private IChannelMerchantService channelMerchantService;

    @Autowired
    private StoreZoneProductService storeZoneProductService;


    @Override
    public PageInfo<StoreZone> getList(StoreZone storeZone, PageParamRequest pageParamRequest) {
        Page<StoreZone> storeZonePage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<StoreZone> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(ObjectUtils.isNotEmpty(storeZone.getName())){
            lambdaQueryWrapper.like(StoreZone::getName, storeZone.getName());
        }
        if(storeZone.getEndTime() != null){
            lambdaQueryWrapper.gt(StoreZone::getEndTime,new Date());
        }
        if(storeZone.getZoneType() != null){
            switch (storeZone.getZoneType()){
                case 0:
                    lambdaQueryWrapper.isNotNull(StoreZone::getPushZoneId);
                    break;
                case 1:
                    lambdaQueryWrapper.isNull(StoreZone::getPushZoneId);
                    break;
                default:
                    throw new CrmebException("专区类型异常!");
            }
        }
        lambdaQueryWrapper.eq(StoreZone::getMerId, storeZone.getMerId());
        lambdaQueryWrapper.eq(StoreZone::getIsDel, 0);
        lambdaQueryWrapper.orderByDesc(StoreZone::getCreateTime);
        List<StoreZone> list = dao.selectList(lambdaQueryWrapper);
        return CommonPage.copyPageInfo(storeZonePage, list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveStoreZone(StoreZone storeZone) {
        checkParam(storeZone);
        //平台专区
        if (storeZone.getMerId() == 0) {
            //推送状态
            if(storeZone.getIsPush() == null){
                throw new CrmebException("请选择推送状态");
            }
        } else {
            storeZone.setPushMerIds(null);
        }
        int insert = dao.insert(storeZone);
        if(insert > 0){
            if (storeZone.getMerId() == 0 && storeZone.getIsPush() == 1) {
                pushMerchant(storeZone,true);
            }
        }
        return insert;
    }

    public List<StoreZone> pushMerchant(StoreZone storeZone,boolean isPush) {
        List<StoreZone> storeZoneList = new ArrayList<>();
        if(isPush){
            //推送到供应商
            List<Integer> merList = JSONObject.parseArray(storeZone.getPushMerIds(), Integer.class);
            if(CollectionUtils.isEmpty(merList)){
                //推送所有供应商
                List<ChannelMerchant> channelMerchantList = channelMerchantService.list(Wrappers.lambdaQuery(ChannelMerchant.class).eq(ChannelMerchant::getIsDel, 0));
                merList = channelMerchantList.stream().map(ChannelMerchant::getId).collect(Collectors.toList());
            }
            for (Integer merId : merList) {
                StoreZone merStoreZone = new StoreZone();
                merStoreZone.setStartTime(storeZone.getStartTime());
                merStoreZone.setEndTime(storeZone.getEndTime());
                merStoreZone.setName(storeZone.getName());
                merStoreZone.setSubName(storeZone.getSubName());
                merStoreZone.setImage(storeZone.getImage());
                merStoreZone.setMerId(merId);
                merStoreZone.setPushZoneId(storeZone.getId());
                storeZoneList.add(merStoreZone);
            }
        }else {
            //修改所有供应商
            storeZoneList = this.list(Wrappers.lambdaQuery(StoreZone.class).eq(StoreZone::getPushZoneId, storeZone.getId()));
            for (StoreZone zone : storeZoneList) {
                zone.setStartTime(storeZone.getStartTime());
                zone.setEndTime(storeZone.getEndTime());
                zone.setName(storeZone.getName());
                zone.setSubName(storeZone.getSubName());
                zone.setImage(storeZone.getImage());
            }
        }
        saveOrUpdateBatch(storeZoneList);
        return storeZoneList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(StoreZone storeZone) {
        StoreZone oldStoreZone = getOne(Wrappers.lambdaQuery(StoreZone.class).eq(StoreZone::getId,storeZone.getId()).eq(StoreZone::getIsDel,0).eq(StoreZone::getMerId,storeZone.getMerId()));
        boolean isPush = true;
        if(oldStoreZone == null){
            throw new CrmebException("该专区不存在");
        }
        //删除专区
        if(Objects.equals(storeZone.getIsDel(),1)){
            if(oldStoreZone.getPushZoneId() != null){
                throw new CrmebException("平台推荐专区不可删除");
            }
            if(storeZone.getMerId() == 0){
                throw new CrmebException("平台专区不可删除");
            }
            oldStoreZone.setIsDel(storeZone.getIsDel());
            return dao.updateById(oldStoreZone);
        }
        checkParam(storeZone);
        //平台专区
        if (storeZone.getMerId() == 0) {
            if(storeZone.getIsPush() == null){
                throw new CrmebException("请选择推送状态");
            }
            if(oldStoreZone.getIsPush() == 1){
                isPush = false;
                if(storeZone.getIsPush() != 1){
                    throw new CrmebException("该专区已推送，不能取消推送");
                }
                //专区已推送，不能编辑商户
                List<Integer> newMerIds = JSONObject.parseArray(storeZone.getPushMerIds(), Integer.class);
                List<Integer> oldMerIds = JSONObject.parseArray(oldStoreZone.getPushMerIds(), Integer.class);
                Collections.sort(newMerIds);
                Collections.sort(oldMerIds);
                if(!newMerIds.toString().equals(oldMerIds.toString())){
                    throw new CrmebException("该专区已推送，不能修改推送商户");
                }
            }
        } else {
            //平台推送专区
            if(oldStoreZone.getPushZoneId() != null){
                if(storeZone.getStartTime().compareTo(oldStoreZone.getStartTime()) != 0 || storeZone.getEndTime().compareTo(oldStoreZone.getEndTime()) != 0){
                    throw new CrmebException("平台推送专区起止时间不能修改");
                }
                if(!Objects.equals(storeZone.getName(),oldStoreZone.getName()) || !Objects.equals(storeZone.getSubName(),oldStoreZone.getSubName())){
                    throw new CrmebException("平台推送专区标题和副标题不能修改");
                }
                if(!Objects.equals(storeZone.getImage(),oldStoreZone.getImage())){
                    throw new CrmebException("平台推送专区banner图不能修改");
                }
            }
            storeZone.setPushMerIds(null);
        }
        int update = dao.updateById(storeZone);
        if(update > 0){
            if (storeZone.getMerId() == 0 && storeZone.getIsPush() == 1) {
                //推送到供应商
                pushMerchantAndProduct(storeZone,isPush);
            }
        }
        return update;
    }

    public void checkParam(StoreZone storeZone) {
        if (storeZone.getStartTime() == null || storeZone.getEndTime() == null) {
            throw new CrmebException("起止时间不能为空");
        }
        if (storeZone.getStartTime().after(storeZone.getEndTime())) {
            throw new CrmebException("开始时间不能大于结束时间");
        }
        if (StringUtils.isBlank(storeZone.getImage())) {
            throw new CrmebException("banner图不能为空");
        }
        //判断图片数量
        List<String> imageList = JSONObject.parseArray(storeZone.getImage(), String.class);
        if (imageList.size() > 9) {
            throw new CrmebException("banner图最多上传9张");
        }
    }

    @Override
    public Integer getAppBarInfo(Integer merId) {
        LambdaQueryWrapper<SystemConfig> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SystemConfig::getFormId,merId);
        lambdaQueryWrapper.eq(SystemConfig::getName, Constants.CONFIG_KEY_APP_BAR_STATUS);
        SystemConfig systemConfig = systemConfigService.getOne(lambdaQueryWrapper);
        if(systemConfig == null){
            return 0;
        }
        return "1".equals(systemConfig.getValue()) ? 1 : 0;
    }

    /**
     * 修改导航栏开启状态
     * @param merId 商户ID
     * @param status 0 不 1是
     * @return
     */
    @Override
    public Boolean updateAppBarStatus(Integer merId, String status) {
        SystemConfig entity = new SystemConfig();
        entity.setValue(status);
        entity.setName(Constants.CONFIG_KEY_APP_BAR_STATUS);
        entity.setTitle(Constants.CONFIG_KEY_APP_BAR_STATUS);
        entity.setFormId(merId);
        LambdaUpdateWrapper<SystemConfig> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SystemConfig::getFormId,merId);
        updateWrapper.eq(SystemConfig::getName,Constants.CONFIG_KEY_APP_BAR_STATUS);
        return systemConfigService.saveOrUpdate(entity,updateWrapper);
    }

    @Override
    public boolean stopStoreZone(Integer id) {
        StoreZone storeZone = getOne(Wrappers.lambdaQuery(StoreZone.class).eq(StoreZone::getMerId, 0).eq(StoreZone::getId, id));
        if(storeZone == null){
            throw new CrmebException("该专区不存在");
        }
        if(storeZone.getStartTime().compareTo(new Date()) > 0 || storeZone.getEndTime().compareTo(new Date()) < 0){
            throw new CrmebException("该专区不是进行中状态");
        }
        Date date = new Date();
        storeZone.setEndTime(date);
        boolean update = updateById(storeZone);
        if(update){
            //终止商户专区
            update(Wrappers.lambdaUpdate(StoreZone.class).set(StoreZone::getEndTime,date).eq(StoreZone::getPushZoneId,storeZone.getId()));
        }
        return update;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean pushStoreZone(Integer id) {
        StoreZone storeZone = getOne(Wrappers.lambdaQuery(StoreZone.class).eq(StoreZone::getId,id).eq(StoreZone::getIsDel,0).eq(StoreZone::getMerId,0));
        if(storeZone == null){
            throw new CrmebException("该专区不存在");
        }
        if(storeZone.getIsPush() == 1){
            throw new CrmebException("该专区已推送");
        }
        storeZone.setIsPush(1);
        boolean update = updateById(storeZone);
        if(update){
            pushMerchantAndProduct(storeZone,true);
        }
        return update;
    }

    /**
     * 功能描述: 总后台已结束专区提供删除
     * @Param: [id]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/3/17 10:09
     */
    @Override
    public Boolean delStoreZone(Integer id) {
        // 当前删除的专区
        StoreZone storeZone = this.getById(id);
        if (Objects.isNull(storeZone) || storeZone.getIsDel() == 1) {
            throw new CrmebException("专区不存在");
        }
        if (storeZone.getEndTime().after(new Date())) {
            throw new CrmebException("专区还未结束，不能删除");
        }
        List<StoreZone> storeZones = this.list(Wrappers.<StoreZone>lambdaQuery()
                .eq(StoreZone::getPushZoneId, storeZone.getId()));
        storeZones.add(storeZone);
        storeZones.forEach(e -> e.setIsDel(1));

        return this.updateBatchById(storeZones);
    }

    public void pushMerchantAndProduct(StoreZone storeZone,boolean isPush) {
        List<StoreZone> storeZoneList = pushMerchant(storeZone,isPush);
        if(CollectionUtils.isEmpty(storeZoneList)){
            return;
        }
        //查询平台推荐商品
        List<StoreZoneProduct> storeZoneProductList = storeZoneProductService.list(Wrappers.lambdaQuery(StoreZoneProduct.class).eq(StoreZoneProduct::getZoneId, storeZone.getId()));
        if (CollectionUtils.isNotEmpty(storeZoneProductList)) {
            List<Integer> productIds = storeZoneProductList.stream().map(StoreZoneProduct::getProductId).collect(Collectors.toList());
            //同步商品
            List<Integer> zoneIdList = storeZoneList.stream().map(StoreZone::getId).collect(Collectors.toList());
            List<Integer> productIdList = new ArrayList<>(productIds);
            storeZoneProductService.addZoneProducts(zoneIdList.get(0),productIdList,zoneIdList);

        }
    }


    /**
     * 开启首页展示时 关闭其他的首页展示
     * @param storeZone
     */
    private void updateStoreZoneStatus(StoreZone storeZone) {
        //首页展示 1 展示 关闭其他
        if (Integer.valueOf("1").equals(storeZone.getStatus())){
            StoreZone updateEntity = new StoreZone();
            updateEntity.setStatus(0);
            LambdaUpdateWrapper<StoreZone> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(StoreZone::getStatus, 1);
            lambdaUpdateWrapper.eq(StoreZone::getMerId,storeZone.getMerId());
            lambdaUpdateWrapper.eq(StoreZone::getIsDel, 0);
            dao.update(updateEntity,lambdaUpdateWrapper);
        }
    }
}

